/**
 * @file    inf_bts7020.c
 * @author  yhy
 * @brief   高策开关接口层
 * @version 1.00
 * @date    2025-07-19
 *
 * @copyright Copyright (c) 2025
 *
 */
#include "inf_bts7020.h"

#include "common_debug.h"
#include "drv_gpio.h"
#include "drv_timer.h"

#include <string.h>

static result_e inf_bts7020_gpio_config(void);
static result_e inf_bts7020_timer_config(void);
static void     inf_bts7020_dsel_switch_handle(void);

/* 高策开关输入通道枚举 */
static const uint32_t bts_pin_num_table[BTS7020_DEVICE_MAX][BTS7020_IN_MAX] = {
    { BTS7020_PUMP_EN_PIN_NUM, BTS7020_VALVE_EN_PIN_NUM },
    { BTS7020_FANL_PIN_NUM, BTS7020_FANR_PIN_NUM },
};

/* 高策开关dsel引脚枚举 */
static const uint32_t bts_dsel_pin_num_table[BTS7020_DEVICE_MAX] = {
    BTS7020_PV_DSEL_PIN_NUM,
    BTS7020_FAN_DSEL_PIN_NUM,
};

/* 高策开关列表 */
bts7020_t bts7020_list[BTS7020_DEVICE_MAX];

/**
 * @brief 高策开关初始化
 *
 * @return result_e 初始化结果, 成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e inf_bts7020_init(void)
{
    /* VALVE_EN（PE8）、PUMP+_EN（PE3） */
    result_e result = inf_bts7020_gpio_config();
    if (result != RESULT_STATUS_OK) {
        return result;
    }

    /* 定时器配置 */
    result = inf_bts7020_timer_config();
    if (result != RESULT_STATUS_OK) {
        return result;
    }

    /* 默认关闭所有高策开关 */
    for (uint8_t i = 0; i < BTS7020_DEVICE_MAX; ++i) {
        bts7020_list[i].in0_en = false;
        bts7020_list[i].in1_en = false;
        bts7020_list[i].dsel   = 0;
        memset(bts7020_list[i].ad_val_buf, 0, sizeof(bts7020_list[i].ad_val_buf));
    }

    return RESULT_STATUS_OK;
}

/**
 * @brief 设置BTS7020知道输入通道状态
 *
 * @param device    设备: PUMP_VALVE or FAN等高策开关
 * @param input     输入通道: VALVE+_EN or PUMP+_EN等
 * @param enable    使能状态: true 使能, false 失能
 * @return result_e 配置结果, 成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e inf_bts7020_set_switch(bts7020_device_e device, bts7020_in_e input, bool enable)
{
    if (device >= BTS7020_DEVICE_MAX || input >= BTS7020_IN_MAX) {
        return RESULT_STATUS_INVALID_PARAM;
    }

    /* 检查当前状态, 如果和设置状态一致则直接返回 */
    bool     cur_status = false;
    uint32_t pin_num    = 0U;

    switch (input) {
    case BTS7020_IN0:
        cur_status = bts7020_list[device].in0_en;
        pin_num    = bts_pin_num_table[device][input];
        break;
    case BTS7020_IN1:
        cur_status = bts7020_list[device].in1_en;
        pin_num    = bts_pin_num_table[device][input];
        break;
    }

    if (cur_status == enable) {
        return RESULT_STATUS_OK;
    }

    /* 不一致, 则设置指定开关状态 */
    snf_gpio_pin_level_e pin_level = enable ? DRV_GPIO_PIN_LEVEL_HIGH : DRV_GPIO_PIN_LEVEL_LOW;
    result_e             result    = snf_drv_gpio_write_pin(pin_num, pin_level);

    if (result == RESULT_STATUS_OK) {
        /* 更新状态 */
        switch (input) {
        case BTS7020_IN0: bts7020_list[device].in0_en = enable; break;
        case BTS7020_IN1: bts7020_list[device].in1_en = enable; break;
        }
    }

    return result;
}

/**
 * @brief 切换dsel引脚状态
 *
 */
static void inf_bts7020_dsel_switch_handle(void)
{
    for (uint8_t i = 0; i < BTS7020_DEVICE_MAX; ++i) {
        bts7020_list[i].dsel = bts7020_list[i].dsel ? 0 : 1;

        snf_gpio_pin_level_e pin_level =
            bts7020_list[i].dsel ? DRV_GPIO_PIN_LEVEL_HIGH : DRV_GPIO_PIN_LEVEL_LOW;
        snf_drv_gpio_write_pin(bts_dsel_pin_num_table[i], pin_level);
    }
}

/**
 * @brief Timer配置, 用于频繁切换dsel引脚
 *
 * @return result_e
 */
static result_e inf_bts7020_timer_config(void)
{
    result_e result = RESULT_STATUS_OK;

    /* 配置定时器3, 用于切换dsel引脚, 50ms调度一次 */
    snf_timer_config_t timer_config = {
        .instance      = TIMER_INSTANCE_TIMER3,
        .prescaler     = 30U - 1U,
        .compare_value = 50000U - 1U,
        .callback      = inf_bts7020_dsel_switch_handle,
    };
    result = snf_drv_timer_init(&timer_config);

    return result;
}

/**
 * @brief 高策开关GPIO配置
 *
 * @return result_e 配置结果, 成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
static result_e inf_bts7020_gpio_config(void)
{
    /* init VALVE+_EN gpio */
    snf_gpio_config_t gpio_config = {
        .pin_num    = BTS7020_VALVE_EN_PIN_NUM,
        .mode       = DRV_GPIO_PIN_MODE_OUTPUT,
        .init_level = DRV_GPIO_PIN_LEVEL_LOW,
    };
    result_e result = snf_drv_gpio_init(&gpio_config);
    if (result != RESULT_STATUS_OK) {
        return result;
    }

    /* init PUMP+_EN gpio */
    gpio_config.pin_num = BTS7020_PUMP_EN_PIN_NUM;
    result              = snf_drv_gpio_init(&gpio_config);
    if (result != RESULT_STATUS_OK) {
        return result;
    }

    /* init DSEL gpio */
    gpio_config.pin_num = BTS7020_PV_DSEL_PIN_NUM;
    result              = snf_drv_gpio_init(&gpio_config);

    /* init FANL gpio */
    gpio_config.pin_num = BTS7020_FANL_PIN_NUM;
    result              = snf_drv_gpio_init(&gpio_config);
    /* init FANR gpio */
    gpio_config.pin_num = BTS7020_FANR_PIN_NUM;
    result              = snf_drv_gpio_init(&gpio_config);
    /* init FAN_DSEL gpio */
    gpio_config.pin_num = BTS7020_FAN_DSEL_PIN_NUM;
    result              = snf_drv_gpio_init(&gpio_config);

    return result;
}
